package com.aco.party.util;

import com.aco.party.model.po.Meta;
import com.aco.party.model.po.Role;
import com.aco.party.model.vo.AccessTokenVo;
import com.aco.party.model.vo.IdNamePair;
import com.aco.party.model.vo.WeixinUserInfo;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by WangShijun on 2016/3/9.
 */
public class WebModelUtil {

    private static final Logger logger = LoggerFactory.getLogger(WebModelUtil.class);

    public static final String SEPARATOR = "_";

    public static final String REDIRECTEDIT = "redirect:edit";

    public static String getImgPath(){
        String parentPath = ConfigResource.getSystemProperty("img_path").endsWith(File.separator) ?
                ConfigResource.getSystemProperty("img_path") : ConfigResource.getSystemProperty("img_path") + File.separator;
        return parentPath;
    }

    public static String getBasePath(){
        String basePath = ConfigResource.getSystemProperty("base_path");
        basePath = basePath.endsWith("/") ?
                basePath.substring(0, basePath.length()) : basePath;
        return basePath;
    }

    public static String get404ImgPath(){
        String basePath = ConfigResource.getSystemProperty("get404img");
        basePath = basePath.endsWith("/") ?
                basePath.substring(0, basePath.length()) : basePath;
        return basePath;
    }

    public static List<IdNamePair> convert2Pairs(List<?> metas){
        List<IdNamePair> pairs = new ArrayList<>();
        if(metas == null || metas.size() == 0) return  pairs;
        for (Object o : metas){
            if(o instanceof Meta) {
                Meta meta = (Meta)o;
                pairs.add(new IdNamePair(meta.getId().intValue(), meta.getName()));
            }
            if(o instanceof Role) {
                Role role = (Role)o;
                pairs.add(new IdNamePair(role.getId().intValue(), role.getDescription()));
            }
        }
        return pairs;
    }

    /**
     * 获取登入token
     */
    public static AccessTokenVo getAccessToken(String code){
        String service = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                ConfigResource.getSystemProperty("weixin_app_id"),
                ConfigResource.getSystemProperty("weixin_app_secret"),
                code
                );
        HttpGet httpGet = new HttpGet(service);
        httpGet.setHeader("Content-Type","application/json");
        HttpResponse response = executeDefaultHttpClient(httpGet);
        String result = null;
        try {
            result = EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
            logger.error("获取accessToken失败！exception msg:" + e.getMessage());
            logger.error(org.apache.commons.lang3.StringUtils.join(e.getStackTrace()));
            return null;
        }
        JSONObject jsonObject = ((JSONObject) JSONValue.parse(result));
        Long errorCode = (Long)jsonObject.get("errcode");
        if(errorCode != null){
            logger.error("获取accessToken失败！errorcode:" + errorCode+" code:" + code +",errmsg:" + jsonObject.get("errmsg"));
            return null;
        }
        String accessToken = (String)jsonObject.get("access_token");
        Long expires_in = (Long)jsonObject.get("expires_in");
        String refresh_token = (String)jsonObject.get("refresh_token");
        String openid = (String)jsonObject.get("openid");
        String scope = (String)jsonObject.get("scope");
        String unionid = (String)jsonObject.get("unionid");
        AccessTokenVo vo = new AccessTokenVo(accessToken,expires_in,refresh_token,openid,scope,unionid);
        return vo;
    }

    public static WeixinUserInfo getUserInfo(String accessToken,String openId){
        String url = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s",
                accessToken,openId);
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Content-Type","application/json");
        HttpResponse response = executeDefaultHttpClient(httpGet);
        String result = null;
        try {
            result = EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
            logger.error("获取accessToken失败！exception msg:" + e.getMessage());
            logger.error(org.apache.commons.lang3.StringUtils.join(e.getStackTrace()));
            return null;
        }
        JSONObject jsonObject = ((JSONObject) JSONValue.parse(result));
        Long errorCode = (Long)jsonObject.get("errcode");
        if(errorCode != null){
            logger.error("获取UserInfo失败！accessToken:"+ accessToken+", openId:" + openId +",errmsg:" + jsonObject.get("errmsg"));
            return null;
        }

        String openid =(String)jsonObject.get("openid");
        String nickname =(String)jsonObject.get("nickname");
        Long sex =(Long)jsonObject.get("sex");
        String province =(String)jsonObject.get("province");
        String city =(String)jsonObject.get("city");
        String country =(String)jsonObject.get("country");
        String headimgurl =(String)jsonObject.get("headimgurl");
        String unionid =(String)jsonObject.get("unionid");

        WeixinUserInfo weixinUserInfo = new WeixinUserInfo(openid,nickname,sex,province,city,country,headimgurl,unionid);
        logger.info("获取的weixin信息如下：" + weixinUserInfo);
        return weixinUserInfo;
    }


    public static org.apache.http.HttpResponse executeDefaultHttpClient(HttpGet httpGet) {
        org.apache.http.HttpResponse response = null;
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, org.apache.http.HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

            org.apache.http.client.HttpClient httpclient = new DefaultHttpClient(ccm, params);
            response = httpclient.execute(httpGet);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return response;
    }
}
